#region Using Statements
using System;
using GameStateManagement;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
#endregion

namespace Life
{
    /// <summary>
    /// The background screen sits behind all the other menu screens.
    /// It draws a background image that remains fixed in place regardless
    /// of whatever transitions the screens on top of it may be doing.
    /// </summary>
    class BackgroundScreen : GameScreen
    {
        #region Fields

        ContentManager content;

        IGameManager gameManager;
        
        Texture2D _cellStrip;
        int _frameCount;
        Rectangle _liveSourceRect;
        Rectangle _deadSourceRect;

        int boardSquareWidth;
        int xOffset;
        int yOffset;

        int boardWidth;
        int boardHeight;
        int[,] backgroundBoard;


        #endregion

        #region Initialization


        /// <summary>
        /// Constructor.
        /// </summary>
        public BackgroundScreen()
        {
            TransitionOnTime = TimeSpan.FromSeconds(0.3);
            TransitionOffTime = TimeSpan.FromSeconds(0.2);

            gameManager = null;
            boardWidth = 0;
            boardHeight = 0;
            backgroundBoard = new int[boardWidth, boardHeight];
        }

        /// <summary>
        /// Loads graphics content for this screen. The background texture is quite
        /// big, so we use our own local ContentManager to load it. This allows us
        /// to unload before going from the menus into the game itself, wheras if we
        /// used the shared ContentManager provided by the Game class, the content
        /// would remain loaded forever.
        /// </summary>
        public override void Activate(bool instancePreserved)
        {
            if (!instancePreserved)
            {
                if (content == null)
                    content = new ContentManager(ScreenManager.Game.Services, "Content");

                // Ensure game manager is initialized
                if (gameManager == null)
                {
                    gameManager = (IGameManager)ScreenManager.Game.Services.GetService(typeof(IGameManager));
                    gameManager.Initialize();
                }

                _cellStrip = content.Load<Texture2D>("cellStrip");

                _frameCount = _cellStrip.Width / 100;
                _liveSourceRect = new Rectangle((_frameCount - 1) * _cellStrip.Height, 0, _cellStrip.Height, _cellStrip.Height);
                _deadSourceRect = new Rectangle(0, 0, _cellStrip.Height, _cellStrip.Height);

                // TODO: This is copied from GameplayScreen.cs

                int horizontalCount = gameManager.BoardWidth;
                int verticalCount = gameManager.BoardHeight;

                // Calculate menu size and available board space

                int availableWidth = ScreenManager.GraphicsDevice.Viewport.Width;
                int availableHeight = ScreenManager.GraphicsDevice.Viewport.Height;

                // Calculate grid size

                int proposedHorizontalWidth = availableWidth / horizontalCount;
                int proposedVerticalWidth = availableHeight / verticalCount;

                if (proposedHorizontalWidth > proposedVerticalWidth)
                    boardSquareWidth = proposedVerticalWidth;
                else
                    boardSquareWidth = proposedHorizontalWidth;

                // Starting new part
                
                boardWidth = availableWidth / boardSquareWidth;
                boardHeight = availableHeight / boardSquareWidth;
                
                xOffset = (availableWidth - boardSquareWidth * boardWidth) / 2;
                yOffset = (availableHeight - boardSquareWidth * boardHeight) / 2;

                backgroundBoard = new int[boardWidth, boardHeight];

                Random rnd = new Random();
                for (int i = 0; i < boardWidth; i++)
                {
                    for (int j = 0; j < boardHeight; j++)
                    {
                        if (rnd.Next(1, 3) == 1)
                            backgroundBoard[i, j] = 1;
                        else
                            backgroundBoard[i, j] = 0;
                    }
                }

                // once the load has finished, we use ResetElapsedTime to tell the game's
                // timing mechanism that we have just finished a very long frame, and that
                // it should not try to catch up.
                ScreenManager.Game.ResetElapsedTime();
            }
        }

        /// <summary>
        /// Unloads graphics content for this screen.
        /// </summary>
        public override void Unload()
        {
            content.Unload();
        }


        #endregion

        #region Update and Draw


        /// <summary>
        /// Updates the background screen. Unlike most screens, this should not
        /// transition off even if it has been covered by another screen: it is
        /// supposed to be covered, after all! This overload forces the
        /// coveredByOtherScreen parameter to false in order to stop the base
        /// Update method wanting to transition off.
        /// </summary>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);
        }


        /// <summary>
        /// Draws the background screen.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
            Rectangle fullscreen = new Rectangle(0, 0, viewport.Width, viewport.Height);

            spriteBatch.Begin();

            int x = xOffset;
            int y = yOffset;

            for (int i = 0; i < boardWidth; i++)
            {
                y = yOffset;

                for (int j = 0; j < boardHeight; j++)
                {
                    Rectangle destinationRect = new Rectangle(x, y, boardSquareWidth, boardSquareWidth);

                    if (backgroundBoard[i, j] == 1)
                    {
                        spriteBatch.Draw(_cellStrip, destinationRect, _liveSourceRect, Color.White * .75f);
                    }
                    else
                    {
                        spriteBatch.Draw(_cellStrip, destinationRect, _deadSourceRect, Color.White * .75f);
                    }

                    y += boardSquareWidth;
                }

                x += boardSquareWidth;
            }

            spriteBatch.End();
        }


        #endregion
    }
}
